(function() { 
    var lang2ext = {
       /* html:       [ 'html', 'htm' ],
        pdf:		[ 'pdf' ],*/ 
        xml:        [ 'xml', 'xsl', 'xsd' ],
        java:       [ 'java' ],
        javascript: [ 'js' ],
        c:          [ 'c' ],
        cpp:        [ 'c++', 'cpp' ],
        perl:       [ 'pl' ],
        python:     [ 'py' ],
        sh:         [ 'sh' ],
        nastran:    [ 'bdf', 'nas' ],
        adams:      [ 'asy', 'sub', 'tpl', 'aci', 'aer', 'aif', 'air', 'asp',
                      'bea', 'bum', 'bus', 'clf', 'cli', 'clu', 'crg', 'csp',
                      'daf', 'dav', 'dcd', 'dcf', 'ddf', 'dif', 'din', 'dpr',
                      'drd', 'dri', 'dti', 'dyn', 'esl', 'esf', 'fdb', 'fbu',
                      'gbu', 'gea', 'gfs', 'gsd', 'gsp', 'hbu', 'hyp', 'jpf',
                      'kcc', 'kno', 'lbf', 'lcf', 'ldf', 'lkf', 'lsf', 'mdl',
                      'osi', 'pa',  'pgf', 'plt', 'ptt', 'pwr', 'rcf', 'rdf',
                      'reb', 'rgf', 'rpc', 'rpt', 'rrm', 'rti', 'sas', 'sgs',
                      'shl', 'spc', 'spr', 'sta', 'ste', 'tcf', 'tdx', 'tir',
                      'tor', 'tsf', 'vas', 'vdf', 'vtt', 'wan', 'wcf', 'wen',
                      'xbt', 'xgr', 'xrf' ],
        properties: [ 'properties' ]
    };
    
    var EXT_2_LANG = { };
    
    for(var l in lang2ext) {
        var e = lang2ext[l];
        for(var i = 0; i < e.length; i++) { EXT_2_LANG[e[i]] = l; }
    }

    var EXT_2_IMG = { jpg: 1, jpeg: 1, png: 1, gif: 1, bmp: 1 };    
    var EXT_2_VID = { mov: 1, webm: 1, mp4: 1, ogv: 1, avi: 1, mpeg: 1, mpg: 1, qt: 1 };    
    var EXT_2_TXT = { txt: 1, text: 1, log: 1 , key:1 };
    var EXT_2_EMBED = { html : 1 , htm : 1 , pdf : 1 , ppt:1,pptx:1 , doc:1,docx:1 , xls:1,xlsx:1 };
    //var EXT_2_EMBED = { html : 1 , htm : 1 , pdf : 1 };
    
    var videos = [ 'WEBM', 'OGG', 'MP4' ];
    
    function splitComma(keys, val) {
        var map = {};
        var k = keys.split(',');
        for(var i = 0; i < k.length; i++) {
            var e = $.trim(k[i]);
            map[e] = val;
        }
        return map;
    }
    
    function init(sod, widget, dom) {
    	var model = sod.model;
    	var args = widget.args;

        var pre = dom.find('#text').hide();
        var img = dom.find('#img').hide();
        var vid = dom.find('#video').hide();
        var iframe = dom.find( "#iframe" ).hide() ;

        var ext2lang = $.extend(EXT_2_LANG, {});
        var ext2img = $.extend(EXT_2_IMG, {});
        var ext2vid = $.extend(EXT_2_VID, {});
        var ext2txt = $.extend(EXT_2_TXT, {});
        var ext2embed = $.extend(EXT_2_EMBED, {});
        
        for(var k in args) {
            if(k.indexOf("lang-") == 0) {
                var l = k.substring(5);
                var map = splitComma(args[k], l);
                $.extend(ext2lang, map);
            }
        }

        if(args.imageExt) $.extend(ext2img, splitComma(args.imageExt, 1));
        if(args.textExt)  $.extend(ext2txt, splitComma(args.textExt,  1));
        if(args.videoExt) $.extend(ext2vid, splitComma(args.videoExt, 1));
        if(args.embedExt) $.extend(ext2embed, splitComma(args.embedExt, 1));
        
        dom.find('#title').css("visibility","visible");
        setTitle(args.title, dom.find('#title'));

        var maxSize = args.maxSize ? parseInt(args.maxSize) : 1024*1024;
        var expr = args.files;
        CSC.rest("query", { oid: model.oid, f: expr, format: 'JSON' }, function(text) {
            var data = eval('('+text+')');
            
            var files;
            var doc;
            if(data.view.fields[0].type == 'Document') {
                files = data.objects[0].attrs[expr].files;
                doc = expr;
            } else {
                files = [ data.objects[0].attrs[expr] ];
                doc = expr.substring(0, expr.lastIndexOf('.'));
            }
            
            files.sort(function(a, b) { return a.name.localeCompare(b.name); });
            
            var html = "<table class='SodFileBrowserList'><tbody>";
            for(var i = 0; i < files.length; i++) {
                var f = files[i];
                var idx = f.name.lastIndexOf(".");
                f.ext = idx == -1 ? "" : f.name.substring(idx+1).toLowerCase();
                
                f.media = ext2img[f.ext] == 1 || ext2vid[f.ext] == 1;
                f.known = f.media  || ext2txt[f.ext] == 1 || ext2embed[ f.ext ] == 1 || ext2lang[f.ext] != null;
                
                f.dis = (!f.media && f.size > maxSize) || !f.known ? "class='Disabled'" : "";
                var e = esc(doc)+"."+f.role;
				
				if( f.ext == "ppt" || f.ext == "pptx" ){
					html += "<tr fid='"+i+"' "+f.dis+">"+
						"<td class='SodFBClick'><img src='../../servlet/ilu?c=fileType&s=16&n="+esc(f.ext)+"'></img></td>"+
						"<td class='SodFBClick SodNoWrap SodMiddle'>"+f.name+"</td>"+
						"<td class='SodFBClick SodRight'>"+CSC.formatSize(f.size)+"</td>"+
						"<td class='SodDownload'><a href='../../servlet/rest/vault?oid="+model.oid+"&expr="+e+"' title='Download' target='_blank'><img src='../../servlet/ilu?c=default&s=16&n=download'></img></a></td></tr>";
				}else{
					html += "<tr fid='"+i+"' "+f.dis+">"+
						"<td class='SodFBClick'><img src='../../servlet/ilu?c=fileType&s=16&n="+esc(f.ext)+"'></img></td>"+
						"<td class='SodFBClick SodNoWrap SodMiddle'>"+f.name+"</td>"+
						"<td class='SodFBClick SodRight'>"+CSC.formatSize(f.size)+"</td>"+
						"<td class='SodDownload'><a href='../../servlet/rest/vault?oid="+model.oid+"&expr="+e+"' title='Download' target='_blank'><img src='../../servlet/ilu?c=default&s=16&n=download'></img></a></td></tr>";
				}
            }
            html += "</tbody></table>";
            
            var onClick = function() {
                var row = $(this).parent();
                
                var idx = parseInt(row.attr('fid'));
                var f = files[idx];
                if(f.dis) return;
                
                dom.find('#name').text(f.name);
                
                dom.find('#files tr').removeClass("ModClick");
                row.addClass("ModClick");
                
                var e = esc(doc);
                var url = "vault?oid="+model.oid+"&expr="+e+"."+f.role;
                
                if( ext2embed[ f.ext ] ){
                	 pre.hide();
                     vid.hide();
                     img.hide();
                     
                     //var _w = args.width ?  args.width  : "100%" ;
             		 //iframe.attr( "width" ,  _w  );
             		 
             		 //var _h = args.height ?  args.height  :  iframe.parent().width() * 1.414  ;
             		 //iframe.attr( "height" ,  _h  );
                     var winHeight =  $(window).height() ; 
					  
					if( f.ext == "ppt" || f.ext == "pptx" || f.ext == "doc" || f.ext == "docx" || f.ext == "xls" || f.ext == "xlsx"){ 
						//iframe.attr( 'src' , '../../pages/officeViewer.jsp?oid='+model.oid + '&expr='+e+'.'+f.role   );
						//CSC.showProgress( "title" , "value" , "text" );
						//iframe.attr( 'src' , '../../pages/office/loading.html' );
						iframe.attr( 'src' , '../../pages/office/officepreview.jsp?oid='+model.oid + '&expr='+e+'.'+f.role );
						iframe.show(); 
						iframe.attr( "height" ,  winHeight - iframe.offset().top - 75 );
						//var _h = $( "div[id='f:w:wm:NavigateWorkspace:treeBox2_body']" ).height();
						//iframe.attr( "height" ,   _h - 250 );
						
//						jQuery.ajax({
//							  type: 'POST',
//							  //url: '../../pages/office/convert.jsp?oid='+model.oid + '&expr='+e+'.'+f.role,
//							  //url: '../../office/convert?oid='+model.oid + '&expr='+e+'.'+f.role,
//							  url: '../../office/convert',
//							  data:{ oid:model.oid , expr: e + '.' + f.role },
//							  async:true,
//							  success: function(data){
//								  if( data && data != "" && data != "Exception")
//									  iframe.attr( 'src' , '../../office/preview/' + data.trim()  );
//								  else
//									  alert( "document preview failed !!! ");
//							  } 
//						});
						
					}else{
						iframe.attr( 'src' , '../../servlet/rest/'+url );
						iframe.show();
						iframe.attr( "height" ,  winHeight - iframe.offset().top - 75 );
						//var _h = $( "div[id='f:w:wm:NavigateWorkspace:treeBox2_body']" ).height();
						//iframe.attr( "height" ,   _h - 250 );
					 }
                     
                     /*
                     window.onresize = function(){ 
                    	 var _h = args.height ?  args.height  :  iframe.parent().width() * 1.414  ;
                 		 iframe.attr( "height" ,  _h  );
                	 }*/ 
                	 
                     $(window).resize(function() {
                    	 //var _h = args.height ?  args.height  :  iframe.parent().width() * 1.414  ;
                    	 
                    	 var _h =  winHeight - iframe.offset().top - 75;
                 		 iframe.attr( "height" ,  _h  );
                    	 
                    	 //var _h = $( "div[id='f:w:wm:NavigateWorkspace:treeBox2_body']" ).height();
 						 //iframe.attr( "height" ,   _h - 250 );
                     });
                     
                }else if(ext2img[f.ext]) {
                    pre.hide();
                    vid.hide();
                    iframe.hide();
                    
                    img.attr('src', '../../servlet/rest/'+url);
                    img.show();
                } else if(ext2vid[f.ext]) {
                    pre.hide();
                    img.hide();
                    iframe.hide();

                    var v = "../../servlet/rest/video?oid="+model.oid+"&expr="+e+"."+f.role+"&format=";
                    var html = "<video controls>"+
                        '<source src="'+v+'WEBM" type="video/webm"></source>'+
                        '<source src="'+v+'OGG"  type="video/ogg"></source>'+
                        '<source src="'+v+'MP4"  type="video/mp4"></source>'+
                        "<p>Your browser does not support at least one of the HTML 5 video formats. Please upgrade to a newer version or use one of the links below.</p>"+
                        "<ul>"+
                        "<li><a href='"+v+"WEBM' target='_blank'>WEBM</a></li>"+
                        "<li><a href='"+v+"OGG'  target='_blank'>OGG</a></li>"+
                        "<li><a href='"+v+"MP4'  target='_blank'>MP4</a></li>"+
                        "</ul>"
                        "</video>";

                    vid.html(html);
                    vid.show();
                } else {
                    CSC.rest("vault", { oid: model.oid, expr: doc+"."+f.role }, function(text) {
                        f.text = text;
                        img.hide();
                        vid.hide();
                        iframe.hide();
                        
                        var lang = ext2lang[f.ext];
                        
                        var code = pre.find('#file').text(text);
                        code.removeClass();
                        hljs.configure({ useBR: false });
                        
                        if(lang) {
                            code.addClass("lang-"+lang);
                            hljs.highlightBlock(code.get()[0]);
                        }
                        
                        pre.show();
                    });
                }
            };
            
            dom.find('#files').html(html).find('td.SodFBClick').bind('click', onClick);
            
            for(var i = 0; i < files.length; i++) {
                if(files[i].dis) continue;
                onClick.call(dom.find('#files tr td.SodRight').eq(i));
                break;
            }
            
            if(files.length == 1 && !files[0].dis) {
                var f = files[0];
                
                dom.find("tr td:first-child").hide();
                dom.find("tr th:first-child").hide();
                
                var e = esc(doc)+"."+f.role;

                var html = "<span>"+CSC.esc(f.name)+"</span> <a href='../../servlet/rest/vault?oid="+model.oid+"&expr="+e+"' title='Download' target='_blank'><img src='../../servlet/ilu?c=default&s=16&n=download'></img></a>";
                
                
                var editSA = widget.args.editSA;
                if(editSA && !f.media) {
                    html += " <img id='edit'   src='../../sod/img/edit.png'  alt='Edit'   title='Edit'   style='cursor: pointer;' class='Hidden'></img>"+
                            " <img id='cancel' src='../../sod/img/close.png' alt='Cancel' title='Cancel' style='cursor: pointer;' class='Hidden'></img>"+
                            " <img id='save'   src='../../sod/img/ok.png'    alt='Save'   title='Save'   style='cursor: pointer;' class='Hidden'></img>";
                }
                
                dom.find('#name').html(html);
                
                if(editSA && !f.media) {
                    var ed = dom.find('#edit');
                    var cl = dom.find('#cancel');
                    var sa = dom.find('#save');

                    var editable = widget.args.editable;
                    if(editable) {
                        CSC.rest("any", { format: "JSON", oid: model.oid, expr: editable}, function(json) {
                            json = eval('('+json+')');
                            if(json.any) checkEditPermission(model, widget, ed);
                        });
                    } else {
                        checkEditPermission(model, widget, ed);
                    }
                    
                    var ta = dom.find('#editor');
                    
                    ed.bind('click', function() {
                        ed.hide(); cl.show(); sa.show();
                        
                        pre.hide();
                        ta.text(f.text);
                        ta.show();
                    });
                    cl.bind('click', function() {
                        ta.hide(); pre.show();
                        
                        ed.show(); cl.hide(); sa.hide();
                    });
                    sa.bind('click', function() {
                        var progress = CSC.showProgress("Updating", 25, "Please wait ...");
                        
                        CSC.rest("query", {oid: model.oid, format: "JSON", f: "project" }, function(json) { // get project
                            CSC.setProgress(progress, 50, "Please wait ...");
                            
                            json = eval("("+json+")");
                            var proj = json.objects[0].attrs.project.oid;
                            var cont = ta.val();
                            
                            var data = { proc: editSA, cmd: "launch", _project: proj, format: "JSON" };
                            data["_"+widget.args.editParamObject] = model.oid;
                            data["_"+widget.args.editParamFile] = cont;

                            CSC.rest("action", data, function(xml) { // process object
                                CSC.setProgress(progress, 75, "Please wait ...");

                                xml = $(xml);
                                
                                var process = xml.find("obj");
                                var status;
                                process.find("attr").each(function() {
                                    var t = $(this);
                                    var n = t.attr('name');
                                    if(n == 'status') { status = t.text(); }
                                });
                                var pid = process.attr('oid');
                                
                                if(status == "Done") {
                                    var outputs = widget.args.editOutput;
                                    if(!outputs) outputs = "outputs";
                                    CSC.rest("query", { format: "JSON", oid: pid, expr: outputs, pageSize: 1 }, function(json) {
                                        progress.dialog('close');
                                        
                                        json = eval('('+json+')');
                                        var oid = json.objects.length == 0 ? model.oid : json.objects[0].oid;
                                        triggerEvent('onSingleObjectSelected', oid);
                                    });
                                } else {
                                    progress.dialog('close');
                                    triggerEvent('onSingleObjectSelected', pid);
                                }
                            });
                        });
                        
                        ta.hide(); pre.show();
                        ed.show(); cl.hide(); sa.hide();
                    });
                }
            }
        });
    }
    
    function checkEditPermission(model, widget, button) {
        CSC.rest("perm", { format: "JSON", action: "execute", oid: model.oid, proc: widget.args.editSA, param: widget.args.editParamObject }, function(json) {
            json = eval('('+json+')');
            if(json.permission) button.show();
        });
    }
    
    var nastran = function(hljs) {
        return {
            cI: true, // language is case-insensitive
            k: 'include sol',
            c: [ hljs.NM,
                 hljs.ASM,
                 { cN: 'comment', b: '\\$', e: '$' }
            ]
        };        
    };

    var adams = function(hljs) {
        return {
            cI: true, // language is case-insensitive
            k: 'def',
            c: [ hljs.NM,
                 hljs.ASM,
                 { cN: 'comment',      b: '\\$',  e: '$'   },
                 { cN: 'keyword',      b: '^\\[', e: '\\]' },
                 { cN: 'javadoc',      b: '#',    e: '$'   },
                 { cN: 'preprocessor', b: '^%',   e: '$'   }
            ]
        };        
    };

    var properties = function(hljs) {
        return {
            cI: true, // language is case-insensitive
            k: 'def',
            c: [ hljs.NM,
                 hljs.ASM,
                 { cN: 'comment',      b: '^\\s*#', e: '$'    },
                 { cN: 'keyword',      b: '^',   e: '\s*=', }
            ]
        };        
    };

    hljs.registerLanguage("nastran",    nastran);
    hljs.registerLanguage("adams",      adams);
    hljs.registerLanguage("properties", properties);
    
    function toPPT(task) { task.lib.notSupported(task, true); }

    return({ onInit: init, toPPT: toPPT });
})();
